var gbk = require('./gbk.js');

var code = require('./code.js');
var process = require('./process.js');
var tpc = require('./terminalParaCode.js');

//终端参数解析
var judgeWhichParameter = function (b, pl) {
	if (b.length == 0) {
		return;
	}
	var id = code.bytes2int4(b.slice(0, 4));
	var length = b[4];
	var paraname = tpc.codeto[id];
	if(paraname){
		pl[paraname] = tpc.typebytetovalue(tpc.codetodatatype[id], b.slice(5,5+length));
		judgeWhichParameter(b.slice(5+length), pl);
	}else{
		judgeWhichParameter(b.slice(5+length), pl);
	}
	return pl;
};

//生成通用终端应答
var TerminalGeneralResponse = function(b){
	var res = {};
	res.snum = code.bytes2int2([b[0],b[1]]);
	res.ResponseId = code.bytes2int2([b[2],b[3]]);
	switch(b[4]){
		case 0: res.result = "成功/确认";	break;
		case 1: res.result = "失败";		break;
		case 2: res.result = "消息有误";	break;
		case 3: res.result = "不支持";		break;
	}
	return res;
};

//生成终端注册信息
var parseTerminalLog = function(b){
	var res = {};
	res.Provincial_ID = code.bytes2int2([b[0],b[1]]);
	res.City_ID = code.bytes2int2([b[2],b[3]]);
	res.Manufacturersbyte = String.fromCharCode(b[4],b[5],b[6],b[7],b[8]);
	res.terminalType = String.fromCharCode.apply(null,b.slice(9,29));
	res.terminalID = String.fromCharCode.apply(null,b.slice(29,36));
	res.color = b[36];
	res.carNumber = gbk.findProvincial(b.slice(37,39))+String.fromCharCode.apply(null,b.slice(39));
	return res;
};

// 生成终端参数应答
var parseTerminalResponse = function(b){
	var paraQueryNo = code.bytes2int2(b.slice(0,2));
	var paraNumber = b[2];
	var paraList = {};
	judgeWhichParameter(b.slice(3),paraList);
	return {
		snum : paraQueryNo,
		count : paraNumber,
		plist : paraList
	};
};

//完成分包、去标识位、转义、校验码校验、去掉校验码
var subpackage = function(buf){
	var _totallen = buf.length;
	var _foundhead = false;
	var _result = [];
	var _package = [];
	for(var i=0;i<_totallen;i++) {
        if (buf[i] == 126 ) {
            if(_foundhead){
                _foundhead = false;
                if (code.checkBytes(_package)) {//校验码校验
                    _result.push( _package.slice(0, _package.length - 1) );
                    return _result;
                } else {
                    console.log('校验码校验错误！');
					return {error: true};
                }
            }else{
                _foundhead = true;
            }
        } else if (_foundhead) {
            if (buf[i] == 125) {//转义
                if (buf[i + 1] == 1) {
                    _package.push(125);
                } else if (buf[i + 1] == 2) {
                    _package.push(126);
                }
                i++;
            } else {
                _package.push(buf[i]);
            }
        }
    }
};

//按消息id解析并返回
var classification = function(id, msg, head, socket){
	switch(id){
		case 1: {// 终端通用应答
			process.response(TerminalGeneralResponse(msg));
			break;
		}
		case 2: {// 终端心跳 消息体为空
			process.heartbeat(socket, head);
			break;
		}
		case 3: {// 终端注销，消息体为空 0x0003
			process.logout(socket, head);
			break;
		}
		case 256: {// 终端注册
			process.login(socket, head, parseTerminalLog(msg));
			break;
		}
		case 258: {// 终端鉴权
			process.authentication(socket, head);
			break;
		}
		case 260: {// 终端参数应答
			process.response(parseTerminalResponse(msg));
			break;
		}
		case 512: {//解析位置回传消息体的主方法
			process.locationInfoReport(socket, head);
			break;
		}
		case 1796:{// 批量解析位置回传消息体的主方法
			process.batchLocationInfoReport(socket, head);
			break;
		}
		case 2304:{// 数据上传透传
			process.textTranslate(socket, head);
			break;
		}
		case 513:{// 查询位置信息应答
			process.locationInfoRespond(socket, head);
			break;
		}
	}
};
var sim_socket = {};
var analysis = function(buf, socket){
	var packages = subpackage(buf);
	if(packages.error){
		return;
	}
	for(var i= 0,len=packages.length;i<len;i++){
		var _p = packages[i];
		var _head = {};
		_head.Id = code.bytes2int2([ _p[0] , _p[1] ]);
		_head.BodyLength = code.bytes2int2([ (_p[2] & 0x3) , _p[3] ]);
		_head.EncryptionMethod = _p[3] & 0x1C;
		_head.IsBag = (_p[2] & 0x20) != 0 ;
		_head.TerminalPhoneNum = parseInt(code.bcd2Str([_p[4],_p[5],_p[6],_p[7],_p[8],_p[9]]));
		_head.MsgNumber = code.bytes2int2( [ _p[10] , _p[11] ] );
		if(!_head.IsBag){
			sim_socket[_head.TerminalPhoneNum] = socket;
			classification(_head.Id, _p.slice(12), _head, socket);
		}else{
			_head.TotalBagNum = code.bytes2int2(_p.slice(12,14));
			_head.PackageNumber = code.bytes2int2(_p.slice(14,16));
		}
	}
};

module.exports = {
	_handler: analysis,
	_socket_map: sim_socket
};